package ds

type Stack[T comparable] struct {
	size int
	head *SinglyLinkedNode[T]
}

func InitializeStack[T comparable]() *Stack[T] {
	return &Stack[T]{
		size: 0,
		head: nil,
	}
}

func (s *Stack[T]) Empty() bool {
	return s.head == nil
}

func (s *Stack[T]) Push(x T) {
	node := &SinglyLinkedNode[T]{
		Val: x,
		Next: s.head,
	}
	s.head = node
	s.size++
}

func (s *Stack[T]) Top() *SinglyLinkedNode[T] {
	return s.head
}

func (s *Stack[T]) Pop() (*SinglyLinkedNode[T], bool) {
	if s.head == nil {
		return nil, false
	}

	node := s.head
	s.head = s.head.Next
	s.size--
	return node, true
}

func (s *Stack[T]) Size() int {
	return s.size
}
